/*!	 widget_defaults.cpp
**	 Template File
**
**	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
**  Copyright (c) 2008 Chris Moore
**  Copyright (c) 2008, 2011, 2012 Carlos López
**
**	This package is free software; you can redistribute it and/or
**	modify it under the terms of the GNU General Public License as
**	published by the Free Software Foundation; either version 2 of
**	the License, or (at your option) any later version.
**
**	This package is distributed in the hope that it will be useful,
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
**	General Public License for more details.
**
*/

#ifdef USING_PCH
#	include "pch.h"
#else
#ifdef HAVE_CONFIG_H
#	include <config.h>
#endif

#include <synfig/general.h>

#include "widgets/widget_defaults.h"
#include "widgets/widget_color.h"
#include "widgets/widget_gradient.h"
#include "dialogs/dialog_color.h"
#include "dialogs/dialog_gradient.h"
#include "app.h"
#include <gtkmm/menu.h>
#include <gtkmm/scale.h>
#include <gtkmm/toolitem.h>
#include <gtkmm/toolitemgroup.h>
#include <gtkmm/toolpalette.h>
#include <synfig/exception.h>
#include <synfigapp/main.h>
#include "canvasview.h"
#include "widgets/widget_enum.h"
#include "widgets/widget_distance.h"

#include <gui/localization.h>

#endif

using namespace std;
using namespace etl;
using namespace synfig;
using namespace studio;

#define DEFAULT_INCREMENT	(0.25)
#define DEFAULT_WIDTH		(synfig::Distance(3,synfig::Distance::SYSTEM_POINTS))

class studio::Widget_Brush : public Gtk::DrawingArea
{
public:
    Widget_Brush()
    {
        add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
        add_events(Gdk::BUTTON1_MOTION_MASK);

        synfigapp::Main::signal_outline_color_changed().connect(sigc::mem_fun(*this, &studio::Widget_Brush::queue_draw));
        synfigapp::Main::signal_fill_color_changed().connect(sigc::mem_fun(*this, &studio::Widget_Brush::queue_draw));
        synfigapp::Main::signal_bline_width_changed().connect(sigc::mem_fun(*this, &studio::Widget_Brush::queue_draw));
        studio::App::signal_instance_selected().connect(sigc::hide(sigc::mem_fun(*this, &studio::Widget_Brush::queue_draw)));
    }

    bool
    on_draw(const Cairo::RefPtr<Cairo::Context> &cr)
    {
        const int h(get_height());
        const int w(get_width());

        float pixelsize(0);

        if (App::get_selected_canvas_view()) {
            const RendDesc& rend_desc(App::get_selected_canvas_view()->get_canvas()->rend_desc());
            pixelsize = synfigapp::Main::get_bline_width().get(Distance::SYSTEM_PIXELS, rend_desc);
        } else {
            RendDesc rend_desc;
            pixelsize = synfigapp::Main::get_bline_width().get(Distance::SYSTEM_PIXELS, rend_desc);
        }

        // Fill in the fill color
        render_color_to_window(cr, Gdk::Rectangle(0, 0, w, h), synfigapp::Main::get_fill_color());

        // Draw in the circle
        Color brush = colorconv_apply_gamma(synfigapp::Main::get_outline_color());
        cr->set_source_rgba(brush.get_r(), brush.get_g(), brush.get_b(), brush.get_a());
        cr->arc(w / 2.0, h / 2.0, pixelsize, 0.0, 360 * M_PI / 180.0);
        cr->fill();
        return true;
    }

    bool
    on_event(GdkEvent *event)
    {
        const int y(static_cast<int>(event->button.y));

        const int h(get_height());

        switch (event->type) {
        case GDK_MOTION_NOTIFY:
            break;

        case GDK_BUTTON_RELEASE:
            if (event->button.button == 1) { // Left click
                Distance dist(synfigapp::Main::get_bline_width());

                if (y < h / 2) { // increase BLine size
                    dist += DEFAULT_INCREMENT;
                } else { // Decrease BLine size
                    dist -= DEFAULT_INCREMENT;
                }

                synfigapp::Main::set_bline_width(dist);
                return true;
            }

            if (event->button.button == 3) {
                // right click on bline width
                synfigapp::Main::set_bline_width(DEFAULT_WIDTH);
                return true;
            }

            break;

        case GDK_SCROLL: {
            Distance dist(synfigapp::Main::get_bline_width());

            switch (event->scroll.direction) {
            case GDK_SCROLL_UP:
            case GDK_SCROLL_RIGHT:
                dist += DEFAULT_INCREMENT;
                break;

            case GDK_SCROLL_DOWN:
            case GDK_SCROLL_LEFT:
                dist -= DEFAULT_INCREMENT;
                break;
            }

            synfigapp::Main::set_bline_width(dist);
            return true;
        }

        default:
            break;
        }

        return false;
    }

};

Widget_Defaults::Widget_Defaults()
{
    Gtk::IconSize iconsize = Gtk::IconSize::from_name("synfig-tiny_icon");

    // Signals
    synfigapp::Main::signal_bline_width_changed().connect(sigc::mem_fun(*this, &studio::Widget_Defaults::bline_width_refresh));
    synfigapp::Main::signal_outline_color_changed().connect(sigc::mem_fun(*this, &studio::Widget_Defaults::otln_color_refresh));
    synfigapp::Main::signal_fill_color_changed().connect(sigc::mem_fun(*this, &studio::Widget_Defaults::fill_color_refresh));
    synfigapp::Main::signal_gradient_changed().connect(sigc::mem_fun(*this, &studio::Widget_Defaults::gradient_refresh));

    otln_color_refresh();
    fill_color_refresh();
    gradient_refresh();
}

Widget_Defaults::~Widget_Defaults()
{
}

void
Widget_Defaults::otln_color_refresh()
{
    _widget_otln_color->set_value(synfigapp::Main::get_outline_color());
}

void
Widget_Defaults::fill_color_refresh()
{
    _widget_fill_color->set_value(synfigapp::Main::get_fill_color());
}

void
Widget_Defaults::gradient_refresh()
{
    _widget_gradient->set_value(synfigapp::Main::get_gradient());
}

void
Widget_Defaults::bline_width_refresh()
{
    widget_bline_width->set_value(synfigapp::Main::get_bline_width());
    brush_entry->set_text(widget_bline_width->get_value().get_string(widget_bline_width->get_digits()));
}

void
Widget_Defaults::on_bline_width_changed()
{
    synfigapp::Main::set_bline_width(widget_bline_width->get_value());
}

void
Widget_Defaults::on_brush_entry_changed()
{
    synfig::Distance distance(synfigapp::Main::get_bline_width());
    distance = synfig::String(brush_entry->get_text());
    synfigapp::Main::set_bline_width(distance);
}

void
Widget_Defaults::on_brush_increase_clicked()
{
    synfig::Distance distance(synfigapp::Main::get_bline_width());
    distance += 1;
    synfigapp::Main::set_bline_width(distance);
}

void
Widget_Defaults::on_brush_decrease_clicked()
{
    synfig::Distance distance(synfigapp::Main::get_bline_width());
    distance -= 1;
    synfigapp::Main::set_bline_width(distance);
}

void
Widget_Defaults::on_otln_color_clicked()
{
    // Left click on outline color
    App::dialog_color->reset();
    App::dialog_color->set_color(synfigapp::Main::get_outline_color());
    App::dialog_color->signal_edited().connect(sigc::ptr_fun(synfigapp::Main::set_outline_color));
    App::dialog_color->present();
}

void
Widget_Defaults::on_fill_color_clicked()
{
    // Left click on fill color
    App::dialog_color->reset();
    App::dialog_color->set_color(synfigapp::Main::get_fill_color());
    App::dialog_color->signal_edited().connect(sigc::ptr_fun(synfigapp::Main::set_fill_color));
    App::dialog_color->present();
}

void
Widget_Defaults::on_swap_color_clicked()
{
    synfigapp::Main::color_swap();
}

void
Widget_Defaults::on_reset_color_clicked()
{
    synfigapp::Main::set_fill_color(Color::white());
    synfigapp::Main::set_outline_color(Color::black());
}

void
Widget_Defaults::on_gradient_clicked()
{
    App::dialog_gradient->set_gradient(synfigapp::Main::get_gradient());
    App::dialog_gradient->reset();
    App::dialog_gradient->signal_edited().connect(sigc::ptr_fun(synfigapp::Main::set_gradient));
    App::dialog_gradient->set_default_button_set_sensitive(false);
    App::dialog_gradient->present();
}
